}
}
- let mut cur = manifest_path.parent().and_then(|p| p.parent());
- while let Some(path) = cur {
+ for path in paths::ancestors(manifest_path).skip(2) {
let manifest = path.join("Cargo.toml");
debug!("find_root - trying {}", manifest.display());
if manifest.exists() {
WorkspaceConfig::Member { .. } => {}
}
}
- cur = path.parent();
}
Ok(None)
use core::MultiShell;
use util::{CargoResult, CargoError, ChainError, Rustc, internal, human};
use util::{Filesystem, LazyCell};
+use util::paths;
use util::toml as cargo_toml;
fn walk_tree<F>(pwd: &Path, mut walk: F) -> CargoResult<()>
where F: FnMut(File, &Path) -> CargoResult<()>
{
- let mut current = pwd;
let mut stash: HashSet<PathBuf> = HashSet::new();
- loop {
+ for current in paths::ancestors(pwd) {
let possible = current.join(".cargo").join("config");
if fs::metadata(&possible).is_ok() {
let file = File::open(&possible)?;
stash.insert(possible);
}
-
- match current.parent() {
- Some(p) => current = p,
- None => break,
- }
}
// Once we're done, also be sure to walk the home directory even if it's not
Err(..) => Err(human("invalid non-unicode path")),
}
}
+
+pub fn ancestors(path: &Path) -> PathAncestors {
+ PathAncestors::new(path)
+}
+
+pub struct PathAncestors<'a> {
+ current: Option<&'a Path>,
+ stop_at: Option<PathBuf>
+}
+
+impl<'a> PathAncestors<'a> {
+ fn new(path: &Path) -> PathAncestors {
+ PathAncestors {
+ current: Some(path),
+ //HACK: avoid reading `~/.cargo/config` when testing Cargo itself.
+ stop_at: env::var("__CARGO_TEST_ROOT").ok().map(PathBuf::from),
+ }
+ }
+}
+
+impl<'a> Iterator for PathAncestors<'a> {
+ type Item = &'a Path;
+
+ fn next(&mut self) -> Option<&'a Path> {
+ if let Some(path) = self.current {
+ self.current = path.parent();
+
+ if let Some(ref stop_at) = self.stop_at {
+ if path == stop_at {
+ self.current = None;
+ }
+ }
+
+ Some(path)
+ } else {
+ None
+ }
+ }
+}
.env_remove("CARGO_HOME")
.env("HOME", support::paths::home())
.env("CARGO_HOME", support::paths::home().join(".cargo"))
+ .env("__CARGO_TEST_ROOT", support::paths::root())
.env_remove("RUSTC")
.env_remove("RUSTFLAGS")
.env_remove("CARGO_INCREMENTAL")